home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / 3DTOSHI2.ZIP / mpg3d / source / G3dpobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-01  |  31.3 KB  |  1,066 lines

  1.  
  2. // g3dpobj.cpp
  3. //
  4. // Copyright (c) 1996 by Toshiaki Tsuji, all rights reserved.
  5.  
  6. #include "stdgfx.h"
  7. #include "g3dpobj.h"
  8. #include "g3dlight.h"
  9.  
  10. GEOMETRYDATA::GEOMETRYDATA ()
  11.   {
  12.     NumPoints = 0;
  13.     NumPolys = 0;
  14.     SharedCounts = NULL;
  15.     PointVisible = NULL;
  16.     FLPLocalPoints = NULL;
  17.     FLPWorldPoints = NULL;
  18.     FLPCameraPoints = NULL;
  19.     FLPScreenPoints = NULL;
  20.     FLPPointLocalNormals = NULL;
  21.     FLPPointWorldNormals = NULL;
  22.     PointIntensities = NULL;
  23.     HazeValues = NULL;
  24.     InverseZ = NULL;
  25.     Polys = NULL;
  26.     FLPPolyLocalPoints = NULL;
  27.     FLPPolyWorldPoints = NULL;
  28.     FLPPolyLocalNormals = NULL;
  29.     FLPPolyWorldNormals = NULL;
  30.   } // End of Constructor for GEOMETRYDATA
  31.  
  32. GEOMETRYDATA::~GEOMETRYDATA ()
  33.   {
  34.     DestroyPoints ();
  35.     DestroyPolys ();  
  36.   } // End of Destructor for GEOMETRYDATA
  37.  
  38. BOOLEAN GEOMETRYDATA::CreatePoints ( LONG NewNumPoints )
  39.   {
  40.     DestroyPoints ();  
  41.     NumPoints = NewNumPoints;
  42.     SharedCounts = new LONG [NumPoints];
  43.     PointVisible = new BYTE [NumPoints];
  44.     
  45.     FLPLocalPoints = new FLPVECTOR3D [NumPoints];  
  46.     FLPWorldPoints = new FLPVECTOR3D [NumPoints];  
  47.     FLPCameraPoints = new FLPVECTOR3D [NumPoints];
  48.     FLPScreenPoints = new FLPVECTOR2D [NumPoints];
  49.  
  50.     FLPPointLocalNormals = new FLPVECTOR3D [NumPoints];
  51.     FLPPointWorldNormals = new FLPVECTOR3D [NumPoints];
  52.     PointIntensities = new float [NumPoints];
  53.     HazeValues = new float [NumPoints];
  54.     InverseZ = new float [NumPoints];
  55.     return SUCCESS;
  56.   } // End of CreatePoints for GEOMETRYDATA
  57.  
  58. BOOLEAN GEOMETRYDATA::CreatePolys ( LONG NewNumPolys )
  59.   {
  60.     DestroyPolys ();  
  61.     NumPolys = NewNumPolys;
  62.     Polys = (G3DPOLY*)malloc(sizeof(G3DPOLY)*NumPolys);
  63.     LONG i;
  64.     for (i=0;i<NumPolys;i++)
  65.       {
  66.         Polys[i] = G3DPOLY ();
  67.         Polys[i].ParentObject = NULL;
  68.       } // End for
  69.  
  70.     FLPPolyLocalPoints = new FLPVECTOR3D* [NumPolys];
  71.     FLPPolyWorldPoints = new FLPVECTOR3D* [NumPolys];
  72.     FLPPolyLocalNormals = new FLPVECTOR3D [NumPolys];
  73.     FLPPolyWorldNormals = new FLPVECTOR3D [NumPolys];
  74.     return SUCCESS;
  75.   } // End of CreatePolys for GEOMETRYDATA
  76.   
  77. VOID GEOMETRYDATA::DestroyPoints ()
  78.   {
  79.     if (FLPLocalPoints!=NULL)
  80.       delete FLPLocalPoints;   
  81.     FLPLocalPoints = NULL;
  82.     
  83.     if (FLPWorldPoints!=NULL)
  84.       delete FLPWorldPoints;   
  85.     FLPWorldPoints = NULL;
  86.     
  87.     if (FLPCameraPoints!=NULL)
  88.       delete FLPCameraPoints;   
  89.     FLPCameraPoints = NULL;
  90.     
  91.     if (FLPScreenPoints!=NULL)
  92.       delete FLPScreenPoints;   
  93.     FLPScreenPoints = NULL;
  94.     
  95.     if (FLPPointLocalNormals!=NULL)
  96.       delete FLPPointLocalNormals;   
  97.     FLPPointLocalNormals = NULL;
  98.     
  99.     if (FLPPointWorldNormals!=NULL)
  100.       delete FLPPointWorldNormals;   
  101.     FLPPointWorldNormals = NULL;
  102.  
  103.     if (PointIntensities!=NULL)
  104.       delete PointIntensities;   
  105.     PointIntensities = NULL;
  106.  
  107.     if (HazeValues!=NULL)
  108.       delete HazeValues;   
  109.     HazeValues = NULL;
  110.  
  111.     if (InverseZ!=NULL)
  112.       delete InverseZ;   
  113.     InverseZ = NULL;
  114.  
  115.     if (SharedCounts!=NULL)
  116.       delete SharedCounts;
  117.     SharedCounts = NULL;
  118.     
  119.     if (PointVisible!=NULL)
  120.       delete PointVisible;
  121.     PointVisible = NULL;
  122.     
  123.     NumPoints = 0;
  124.   } // End of DestroyPoints for GEOMETRYDATA
  125.  
  126. VOID GEOMETRYDATA::DestroyPolys ()
  127.   {
  128.     if (Polys!=NULL)  
  129.       free ( Polys );
  130.     Polys = NULL;
  131.     
  132.     if (FLPPolyLocalPoints!=NULL)
  133.       delete FLPPolyLocalPoints;   
  134.     FLPPolyLocalPoints = NULL;
  135.     
  136.     if (FLPPolyWorldPoints!=NULL)
  137.       delete FLPPolyWorldPoints;   
  138.     FLPPolyWorldPoints = NULL;
  139.     
  140.     if (FLPPolyLocalNormals!=NULL)
  141.       delete FLPPolyLocalNormals;   
  142.     FLPPolyLocalNormals = NULL;
  143.     
  144.     if (FLPPolyWorldNormals!=NULL)
  145.       delete FLPPolyWorldNormals;   
  146.     FLPPolyWorldNormals = NULL;
  147.     
  148.     NumPolys = 0;
  149.   } // End of DestroyPolys for GEOMETRYDATA
  150.  
  151.  
  152. //********************************************************
  153. //
  154. // G3D Polygon
  155. //    
  156. //********************************************************
  157.  
  158. G3DPOLYHEDRON::G3DPOLYHEDRON () : G3DOBJECT ()
  159.   {
  160.     Type = OBJECT_TYPE_POLYHEDRON;  
  161.     InitGeometryData ();
  162.     CurDetail = MAX_DETAIL;
  163.     ClockWised = FALSE;
  164.     DetailData[MAX_DETAIL].FaceFlags = FACE_TEXTURE;
  165.     DetailData[MAX_DETAIL].ShadeFlags = SHADE_GOURAUD;
  166.     DetailData[MED_DETAIL].FaceFlags = FACE_SOLID;
  167.     DetailData[MED_DETAIL].ShadeFlags = SHADE_FLAT;
  168.     DetailData[MIN_DETAIL].FaceFlags = FACE_WIREFRAME;
  169.     DetailData[MIN_DETAIL].ShadeFlags = SHADE_NONE;
  170.     MorphData = NULL;  
  171.     TextureMapped = FALSE;
  172.   } // End of Constructor for G3DPOLYHEDRON
  173.  
  174. G3DPOLYHEDRON::~G3DPOLYHEDRON ()
  175.   {
  176.     DestroyGeometryData ();
  177.     DestroyMorphData ();
  178.   } // End of Destructor for G3DPOLYHEDRON
  179.  
  180. VOID G3DPOLYHEDRON::SetMaterial ( G3DMATERIAL* Material )
  181.  
  182.   {
  183.     LONG i;
  184.     for (i=0;i<GeometryData.NumPolys;i++)
  185.       {
  186.         GeometryData.Polys[i].Material = Material;
  187.       } // End for
  188.   } // End of SetMaterial for G3DPOLYHEDRON
  189.  
  190. VOID G3DPOLYHEDRON::InitGeometryData ()
  191.   {
  192.     GeometryData = GEOMETRYDATA ();  
  193.   } // End of InitDetailData for G3DPOLYHEDRON
  194.  
  195. VOID G3DPOLYHEDRON::CreateGeometryData ( LONG NumPoints, LONG NumPolys )
  196.   {
  197.     CreateGeometryPoints ( NumPoints );  
  198.     CreateGeometryPolys ( NumPolys );  
  199.   } // End of CreateDetailData for G3DPOLYHEDRON
  200.  
  201. VOID G3DPOLYHEDRON::CreateGeometryPoints ( LONG NumPoints )
  202.   {
  203.     GeometryData.CreatePoints ( NumPoints );
  204.   } // End of CreateGeometryPoints for G3DPOLYHEDRON
  205.  
  206. VOID G3DPOLYHEDRON::CreateGeometryPolys ( LONG NumPolys )
  207.   {
  208.     GeometryData.CreatePolys ( NumPolys );    
  209.     LONG i;
  210.     for (i=0;i<GeometryData.NumPolys;i++)
  211.       {
  212.         GeometryData.Polys[i].ParentObject = this;
  213.       } // End for
  214.   } // End of CreateGeometryPolys for G3DPOLYHEDRON
  215.  
  216. VOID G3DPOLYHEDRON::DestroyGeometryPoints ()
  217.   {
  218.     GeometryData.DestroyPoints();
  219.   } // End of DestroyGeometryPoints for G3DPOLYHEDRON
  220.  
  221. VOID G3DPOLYHEDRON::DestroyGeometryPolys ()
  222.   {
  223.     GeometryData.DestroyPolys();
  224.   } // End of DestoryGeometryPoints for G3DPOLYHEDRON
  225.  
  226. VOID G3DPOLYHEDRON::DestroyGeometryData ()
  227.   {
  228.     DestroyGeometryPoints ();  
  229.     DestroyGeometryPolys ();  
  230.   } // End of DestroyDetailData for G3DPOLYHEDRON
  231.  
  232. VOID G3DPOLYHEDRON::SetDetailData ( float Distance )
  233.   {
  234.     LONG i;
  235.     CurDetail = -1;  
  236.     for (i=MAX_DETAIL;i>=MIN_DETAIL;i--)
  237.       {
  238.         if (Distance<=DetailData[i].MaxDistance)
  239.           {
  240.             CurDetail = i;            
  241.           } // End for  
  242.       } // End for
  243.   } // End of SetDetailData for G3DPOLYHEDRON
  244.  
  245. VOID G3DPOLYHEDRON::SetFaceFlags ( LONG Level, LONG Flags )
  246.   {
  247.     DetailData[Level].FaceFlags = Flags;  
  248.   } // End of SetFaceFlags for G3DPOLYHEDRON
  249.  
  250. VOID G3DPOLYHEDRON::SetShadeFlags ( LONG Level, LONG Flags )
  251.   {
  252.     DetailData[Level].ShadeFlags = Flags;  
  253.   } // End of SetShadeFlags for G3DPOLYHEDRON
  254.  
  255. VOID G3DPOLYHEDRON::UpdateLocalToWorld ()
  256.   {
  257.     G3DOBJECT::UpdateLocalToWorld ();
  258.  
  259.     LONG i;
  260.     LONG NumPoints = GeometryData.NumPoints;
  261.     LONG NumPolys = GeometryData.NumPolys;
  262.     FLPVECTOR3D *LocalPoints;
  263.     FLPVECTOR3D *WorldPoints;
  264.     FLPVECTOR3D *LocalNormals;
  265.     FLPVECTOR3D *WorldNormals;
  266.  
  267.     LocalPoints = GeometryData.FLPLocalPoints;
  268.     WorldPoints = GeometryData.FLPWorldPoints;
  269.     
  270.     LocalNormals = GeometryData.FLPPointLocalNormals;
  271.     WorldNormals = GeometryData.FLPPointWorldNormals;
  272.     
  273.     float x,y,z;
  274.     float nx,ny,nz;
  275.  
  276.     float M00,M01,M02;
  277.     float M10,M11,M12;
  278.     float M20,M21,M22;
  279.     float M30,M31,M32;
  280.     float *MatrixPtr;
  281.  
  282.     MatrixPtr = &(ResultMatrix[0][0]);
  283.  
  284.     M00 = (*MatrixPtr++);
  285.     M01 = (*MatrixPtr++);
  286.     M02 = (*MatrixPtr++);
  287.     MatrixPtr++;
  288.         
  289.     M10 = (*MatrixPtr++);
  290.     M11 = (*MatrixPtr++);
  291.     M12 = (*MatrixPtr++);
  292.     MatrixPtr++;
  293.         
  294.     M20 = (*MatrixPtr++);
  295.     M21 = (*MatrixPtr++);
  296.     M22 = (*MatrixPtr++);
  297.     MatrixPtr++;
  298.         
  299.     M30 = (*MatrixPtr++);
  300.     M31 = (*MatrixPtr++);
  301.     M32 = (*MatrixPtr);
  302.  
  303.     BOOLEAN IsGouraud;
  304.         
  305.     if ((DetailData[CurDetail].ShadeFlags==SHADE_GOURAUD)&&(LightSource!=NULL))
  306.       IsGouraud = TRUE;
  307.     else
  308.       IsGouraud = FALSE;
  309.       
  310.     for (i=0;i<NumPoints;i++)
  311.       {
  312.         x = LocalPoints->x;       
  313.         y = LocalPoints->y;
  314.         z = LocalPoints->z;
  315.  
  316.         WorldPoints->x = x*M00+y*M10+z*M20+M30;
  317.         WorldPoints->y = x*M01+y*M11+z*M21+M31;
  318.         WorldPoints->z = x*M02+y*M12+z*M22+M32;
  319.                 
  320.         if (IsGouraud)
  321.           {
  322.             nx = LocalNormals->x;       
  323.             ny = LocalNormals->y;
  324.             nz = LocalNormals->z;
  325.  
  326.             WorldNormals->x = nx*M00+ny*M10+nz*M20+M30 - WorldPoints->x;
  327.             WorldNormals->y = nx*M01+ny*M11+nz*M21+M31 - WorldPoints->y;
  328.             WorldNormals->z = nx*M02+ny*M12+nz*M22+M32 - WorldPoints->z;
  329.             
  330.             LocalNormals++;
  331.             WorldNormals++;                      
  332.           } // End if  
  333.         
  334.         LocalPoints++;
  335.         WorldPoints++;                      
  336.       } // End for      
  337.  
  338.     LocalNormals = GeometryData.FLPPolyLocalNormals;
  339.     WorldNormals = GeometryData.FLPPolyWorldNormals;
  340.  
  341.     FLPVECTOR3D **PolyWorldPoints;
  342.     G3DPOLY *Polys;
  343.     float x0,y0,z0;
  344.     float x1,y1,z1;
  345.     float x2,y2,z2;
  346.     LONG Point1,Point2;
  347.  
  348.     PolyWorldPoints = GeometryData.FLPPolyWorldPoints;
  349.     Polys = GeometryData.Polys;
  350.     
  351.     for (i=0;i<NumPolys;i++)
  352.       {
  353.         nx = LocalNormals->x;       
  354.         ny = LocalNormals->y;
  355.         nz = LocalNormals->z;
  356.  
  357.         x = nx*M00+ny*M10+nz*M20+M30;
  358.         y = nx*M01+ny*M11+nz*M21+M31;
  359.         z = nx*M02+ny*M12+nz*M22+M32;
  360.  
  361.         x0 = (*PolyWorldPoints)->x;
  362.         y0 = (*PolyWorldPoints)->y;
  363.         z0 = (*PolyWorldPoints)->z;
  364.         
  365.         WorldNormals->x = x - x0;
  366.         WorldNormals->y = y - y0;
  367.         WorldNormals->z = z - z0;
  368.         
  369.         LocalNormals++;
  370.         WorldNormals++;
  371.         PolyWorldPoints++;
  372.  
  373.         Point1 = Polys->Points[1];
  374.         Point2 = Polys->Points[2];
  375.  
  376.         x1 = GeometryData.FLPWorldPoints[Point1].x;
  377.         y1 = GeometryData.FLPWorldPoints[Point1].y;
  378.         z1 = GeometryData.FLPWorldPoints[Point1].z;
  379.         
  380.         x2 = GeometryData.FLPWorldPoints[Point2].x;
  381.         y2 = GeometryData.FLPWorldPoints[Point2].y;
  382.         z2 = GeometryData.FLPWorldPoints[Point2].z;
  383.  
  384.         Polys->WorldMinX = MinValue ( x0, MinValue ( x1, x2 ) );
  385.         Polys->WorldMinY = MinValue ( y0, MinValue ( y1, y2 ) );
  386.         Polys->WorldMinZ = MinValue ( z0, MinValue ( z1, z2 ) );
  387.         Polys->WorldMaxX = MaxValue ( x0, MaxValue ( x1, x2 ) );
  388.         Polys->WorldMaxY = MaxValue ( y0, MaxValue ( y1, y2 ) );
  389.         Polys->WorldMaxZ = MaxValue ( z0, MaxValue ( z1, z2 ) );
  390.         
  391.         Polys++;
  392.       } // End for      
  393.   } // End of UpdateLocalToWorld for G3DPOLYHEDRON
  394.  
  395. VOID G3DPOLYHEDRON::UpdateWorldToCamera ( G3DMATRIX CameraMatrix,
  396.                                           CAMERADATA *CameraData )
  397.   {
  398.     LONG i;
  399.     LONG NumPoints = GeometryData.NumPoints;
  400.     FLPVECTOR3D *WorldPoints;
  401.     FLPVECTOR3D *CameraPoints;
  402.     FLPVECTOR3D *PointWorldNormals;
  403.     FLPVECTOR2D *ScreenPoints;
  404.     float *Intensities;
  405.     float *HazeValues;
  406.     float *InverseZPtr;
  407.  
  408.     G3DOBJECT::UpdateWorldToCamera ( CameraMatrix, CameraData );
  409.  
  410.     if (IsObjectVisible()==FALSE)
  411.       return;
  412.     
  413.     WorldPoints = GeometryData.FLPWorldPoints;
  414.     PointWorldNormals = GeometryData.FLPPointWorldNormals;
  415.     CameraPoints = GeometryData.FLPCameraPoints;
  416.     ScreenPoints = GeometryData.FLPScreenPoints;
  417.     Intensities = GeometryData.PointIntensities;
  418.     HazeValues = GeometryData.HazeValues;
  419.     InverseZPtr = GeometryData.InverseZ;
  420.     
  421.     float M00,M01,M02;
  422.     float M10,M11,M12;
  423.     float M20,M21,M22;
  424.     float M30,M31,M32;
  425.     float *MatrixPtr;
  426.  
  427.     MatrixPtr = &(CameraMatrix[0][0]);
  428.  
  429.     M00 = (*MatrixPtr++);
  430.     M01 = (*MatrixPtr++);
  431.     M02 = (*MatrixPtr++);
  432.     MatrixPtr++;
  433.         
  434.     M10 = (*MatrixPtr++);
  435.     M11 = (*MatrixPtr++);
  436.     M12 = (*MatrixPtr++);
  437.     MatrixPtr++;
  438.         
  439.     M20 = (*MatrixPtr++);
  440.     M21 = (*MatrixPtr++);
  441.     M22 = (*MatrixPtr++);
  442.     MatrixPtr++;
  443.         
  444.     M30 = (*MatrixPtr++);
  445.     M31 = (*MatrixPtr++);
  446.     M32 = (*MatrixPtr);
  447.  
  448.     // Initialize all the points are invisible
  449.     BYTE *PointVisible;
  450.     PointVisible = GeometryData.PointVisible;
  451.     memset ( PointVisible, 0, NumPoints );
  452.  
  453.     CheckMeshVisibility ( CameraData );
  454.  
  455.     LONG ShadeFlags;
  456.     ShadeFlags = MinValue ( DetailData[CurDetail].ShadeFlags, CameraData->ShadeFlags );
  457.      
  458.     float x,y,z;
  459.     float cx,cy,cz;
  460.     float CenterX = CameraData->CenterX;
  461.     float CenterY = CameraData->CenterY;
  462.     float ViewDistance = CameraData->ViewDistance;
  463.     BOOLEAN IsGouraud;
  464.     BOOLEAN DepthCueing;
  465.     float DepthScale;
  466.     BOOLEAN DoHaze;
  467.     float HazeScale;
  468.     float HazeLevels;
  469.  
  470.     DepthCueing = CameraData->DepthCueing;
  471.     DepthScale = CameraData->DepthScale;
  472.     
  473.     DoHaze = CameraData->DoHaze;
  474.     HazeLevels = (float)(CameraData->HazeLevels-1);
  475.     HazeScale = CameraData->HazeScale;
  476.     
  477.     if ((ShadeFlags==SHADE_GOURAUD)&&(LightSource!=NULL))
  478.       {
  479.         IsGouraud = TRUE;  
  480.       } // End if  
  481.     else
  482.       IsGouraud = FALSE;  
  483.  
  484.     for (i=0;i<NumPoints;i++)
  485.       {
  486.         if (*PointVisible)
  487.           {      
  488.             x = WorldPoints->x;       
  489.             y = WorldPoints->y;
  490.             z = WorldPoints->z;
  491.  
  492.             if (IsGouraud)
  493.               *Intensities = LightSource->ComputeIntensity ( WorldPoints, PointWorldNormals );  
  494.             
  495.             cx = x*M00+y*M10+z*M20+M30;
  496.             cy = x*M01+y*M11+z*M21+M31;
  497.             cz = x*M02+y*M12+z*M22+M32;
  498.  
  499.             if (cz==0)
  500.               cz = (float)0.1;
  501.  
  502.             float Ratio;
  503.             *InverseZPtr = Ratio = (float)1/cz;
  504.             if (DepthCueing)
  505.               {
  506.                 if (cz>DepthScale)
  507.                   (*Intensities) *= Ratio*DepthScale;  
  508.               } // End if
  509.               
  510.             if (DoHaze)
  511.               {
  512.                 if (cz>HazeScale)
  513.                   (*HazeValues) = Ratio*65536*HazeScale*HazeLevels;
  514.                 else  
  515.                   (*HazeValues) = HazeLevels*65536;
  516.               } // End if  
  517.             
  518.             ScreenPoints->x = ViewDistance*Ratio*cx + CenterX;
  519.             ScreenPoints->y = -ViewDistance*Ratio*cy + CenterY;
  520.  
  521.             CameraPoints->x = cx;
  522.             CameraPoints->y = cy;
  523.             CameraPoints->z = cz;
  524.           } // End if
  525.                                   
  526.         PointVisible++;
  527.         WorldPoints++;
  528.         CameraPoints++;
  529.         ScreenPoints++;
  530.         PointWorldNormals++;
  531.         Intensities++;
  532.         HazeValues++;
  533.         InverseZPtr++;
  534.       } // End for
  535.  
  536.     GetPolyMinMax ();  
  537.   } // End of UpdateWorldToCamera for G3DPOLYHEDRON
  538.  
  539. VOID G3DPOLYHEDRON::CheckMeshVisibility ( CAMERADATA *CameraData ) 
  540.   {
  541.     LONG i,NumPolys;
  542.     G3DPOLY *PolyPtr;
  543.     FLPVECTOR3D *PointList,*Point;
  544.     FLPVECTOR3D CameraPoint = CameraData->CameraPoint;
  545.     LONG NumVisibleShapes = CameraData->NumVisibleShapes;
  546.     G3DSHAPE **VisibleShapes = CameraData->VisibleShapes;
  547.  
  548.     PolyPtr = GeometryData.Polys;
  549.     NumPolys = GeometryData.NumPolys;
  550.     PointList = GeometryData.FLPWorldPoints;
  551.  
  552.     FLPVECTOR3D DirV;
  553.     FLPVECTOR3D *Normals;
  554.     float DotProduct;
  555.     BYTE *PointVisible;
  556.     BOOLEAN IsFlat;
  557.  
  558.     LONG ShadeFlags;
  559.     ShadeFlags = MinValue ( DetailData[CurDetail].ShadeFlags, CameraData->ShadeFlags );
  560.     
  561.     if ((ShadeFlags==SHADE_FLAT)&&(LightSource!=NULL))
  562.       IsFlat = TRUE;
  563.     else
  564.       IsFlat = FALSE;     
  565.  
  566.     PointVisible = GeometryData.PointVisible;
  567.     Normals = GeometryData.FLPPolyWorldNormals;
  568.     
  569.     LONG List0,List1,List2;
  570.     
  571.     for (i=0;i<NumPolys;i++)
  572.       {
  573.         List0 = PolyPtr->Points[0];
  574.         Point = &(PointList[List0]);
  575.         FLPVectorSub ( &CameraPoint, Point, &DirV );
  576.         DotProduct = FLPVectorDot ( Normals, &DirV );
  577.         if (DotProduct<=0)
  578.           PolyPtr->Visible = FALSE;
  579.         else
  580.           {
  581.             PolyPtr->Visible = TRUE;
  582.             VisibleShapes[NumVisibleShapes] = PolyPtr;
  583.             NumVisibleShapes++;
  584.             List1 = PolyPtr->Points[1];
  585.             List2 = PolyPtr->Points[2];
  586.             PointVisible[List0] = 1;
  587.             PointVisible[List1] = 1;
  588.             PointVisible[List2] = 1;
  589.  
  590.             if (IsFlat)
  591.               {
  592.                 PolyPtr->Intensity =
  593.                   LightSource->ComputeIntensity ( Point, Normals ); 
  594.               } // End if
  595.           } // End else
  596.         Normals++;
  597.         PolyPtr++;
  598.       } // End for
  599.     CameraData->NumVisibleShapes = NumVisibleShapes;  
  600.   } // End of CheckMeshVisiblity for G3DPOLYHEDRON
  601.  
  602. VOID G3DPOLYHEDRON::CountPointShare ()
  603.   {
  604.     LONG i;
  605.     LONG List0,List1,List2;
  606.     
  607.     // Initialize as 0  
  608.     for (i=0;i<GeometryData.NumPoints;i++)
  609.       {
  610.         GeometryData.SharedCounts[i] = 0;
  611.         GeometryData.FLPPointLocalNormals[i].x = (float)0;
  612.         GeometryData.FLPPointLocalNormals[i].y = (float)0;
  613.         GeometryData.FLPPointLocalNormals[i].z = (float)0;
  614.       } // End for
  615.  
  616.     // Count
  617.     for (i=0;i<GeometryData.NumPolys;i++)
  618.       {
  619.         List0 = GeometryData.Polys[i].Points[0];  
  620.         List1 = GeometryData.Polys[i].Points[1];  
  621.         List2 = GeometryData.Polys[i].Points[2];  
  622.         GeometryData.SharedCounts[List0]++;  
  623.         GeometryData.SharedCounts[List1]++;  
  624.         GeometryData.SharedCounts[List2]++;
  625.         GeometryData.FLPPolyLocalPoints[i] = &(GeometryData.FLPLocalPoints[List0]);
  626.         GeometryData.FLPPolyWorldPoints[i] = &(GeometryData.FLPWorldPoints[List0]);
  627.       } // End for
  628.   } // End of CountPointShare for G3DPOLYHEDRON
  629.  
  630. VOID G3DPOLYHEDRON::ComputePolyLocalNormals ()
  631.   {
  632.     LONG i;
  633.     FLPVECTOR3D V1,V2,Normal;
  634.     FLPVECTOR3D *PointLocalNormals;
  635.  
  636.     PointLocalNormals = GeometryData.FLPPointLocalNormals;
  637.  
  638.     LONG List0,List1,List2;
  639.     
  640.     for (i=0;i<GeometryData.NumPolys;i++)
  641.       {
  642.         List0 = GeometryData.Polys[i].Points[0];  
  643.         List1 = GeometryData.Polys[i].Points[1];  
  644.         List2 = GeometryData.Polys[i].Points[2];
  645.  
  646.         FLPVectorSub ( &(GeometryData.FLPLocalPoints[List0]),
  647.                        &(GeometryData.FLPLocalPoints[List1]),
  648.                        &V1 );
  649.         FLPVectorSub ( &(GeometryData.FLPLocalPoints[List0]),
  650.                        &(GeometryData.FLPLocalPoints[List2]),
  651.                        &V2 );
  652.         FLPVectorCross ( &V1, &V2, &Normal );
  653.         FLPVectorNormalize ( &Normal );
  654.  
  655.         if (ClockWised)  // If clock-wise, then flip normal
  656.           {
  657.             Normal.x = -Normal.x;  
  658.             Normal.y = -Normal.y;  
  659.             Normal.z = -Normal.z;  
  660.           } // End if
  661.         
  662.         PointLocalNormals[List0].x += Normal.x;
  663.         PointLocalNormals[List0].y += Normal.y;
  664.         PointLocalNormals[List0].z += Normal.z;
  665.  
  666.         PointLocalNormals[List1].x += Normal.x;
  667.         PointLocalNormals[List1].y += Normal.y;
  668.         PointLocalNormals[List1].z += Normal.z;
  669.  
  670.         PointLocalNormals[List2].x += Normal.x;
  671.         PointLocalNormals[List2].y += Normal.y;
  672.         PointLocalNormals[List2].z += Normal.z;
  673.  
  674.         FLPVectorAdd ( &Normal, &(GeometryData.FLPLocalPoints[List0]),
  675.                        &(GeometryData.FLPPolyLocalNormals[i]) );
  676.       } // End for
  677.   } // End of ComputePolyLocalNormals for G3DPOLYHEDRON
  678.  
  679. VOID G3DPOLYHEDRON::ComputePointLocalNormals ()
  680.   {
  681.     LONG i;
  682.     FLPVECTOR3D *LocalPoints;
  683.     FLPVECTOR3D *Normals;
  684.  
  685.     LocalPoints = GeometryData.FLPLocalPoints;
  686.     Normals = GeometryData.FLPPointLocalNormals;
  687.  
  688.     for (i=0;i<GeometryData.NumPoints;i++)
  689.       {
  690.         float Ratio;  
  691.         if (GeometryData.SharedCounts[i]>0)
  692.           {
  693.             Ratio = (float)1/(float)GeometryData.SharedCounts[i];
  694.             Normals[i].x *= Ratio;  
  695.             Normals[i].y *= Ratio;  
  696.             Normals[i].z *= Ratio;
  697.           } // End if
  698.  
  699.         FLPVectorNormalize ( &(Normals[i]) );
  700.         Normals[i].x += LocalPoints[i].x;
  701.         Normals[i].y += LocalPoints[i].y;
  702.         Normals[i].z += LocalPoints[i].z;
  703.       } // End for  
  704.   } // End of ComputePointLocalNormals for G3DPOLYHEDRON
  705.  
  706. VOID G3DPOLYHEDRON::GetPolyMinMax ()
  707.   {
  708.     G3DPOLY *PolyPtr;
  709.     FLPVECTOR3D *CameraPoints;
  710.     
  711.     PolyPtr = GeometryData.Polys;
  712.     CameraPoints = GeometryData.FLPCameraPoints;
  713.  
  714.     LONG i;
  715.     LONG List0,List1,List2;
  716.     float z0,z1,z2;
  717.     
  718.     for (i=0;i<GeometryData.NumPolys;i++)
  719.       {
  720.         if (PolyPtr->Visible)
  721.           {
  722.             List0 = PolyPtr->Points[0];  
  723.             List1 = PolyPtr->Points[1];  
  724.             List2 = PolyPtr->Points[2];
  725.             z0 = CameraPoints[List0].z;
  726.             z1 = CameraPoints[List1].z;
  727.             z2 = CameraPoints[List2].z;
  728.  
  729.             PolyPtr->MinZ = MinValue ( z0, MinValue ( z1, z2 ) );
  730.             PolyPtr->MaxZ = MaxValue ( z0, MaxValue ( z1, z2 ) );
  731.           } // End if  
  732.         PolyPtr++;
  733.       } // End for  
  734.   } // End of GetPolyMinMax for G3DPOLYHEDRON
  735.  
  736. VOID G3DPOLYHEDRON::MapTexture ( float U0, float V0,
  737.                                  float U1, float V1,
  738.                                  float U2, float V2 )
  739.   {
  740.     double IntPart;
  741.     if (U0>(float)1.0)
  742.       U0 = modf ( (double)U0, &IntPart );
  743.     if (V0>(float)1.0)
  744.       V0 = modf ( (double)V0, &IntPart );
  745.     if (U1>(float)1.0)
  746.       U1 = modf ( (double)U1, &IntPart );
  747.     if (V1>(float)1.0)
  748.       V1 = modf ( (double)V1, &IntPart );
  749.     if (U2>(float)1.0)
  750.       U2 = modf ( (double)U2, &IntPart );
  751.     if (V2>(float)1.0)
  752.       V2 = modf ( (double)V2, &IntPart );
  753.     
  754.     LONG i;
  755.     for (i=0;i<GeometryData.NumPolys;i++)
  756.       {
  757.         GeometryData.Polys[i].TexCoords[0].x = U0*255*65536;
  758.         GeometryData.Polys[i].TexCoords[0].y = V0*255*65536;
  759.         GeometryData.Polys[i].TexCoords[1].x = U1*255*65536;
  760.         GeometryData.Polys[i].TexCoords[1].y = V1*255*65536;
  761.         GeometryData.Polys[i].TexCoords[2].x = U2*255*65536;
  762.         GeometryData.Polys[i].TexCoords[2].y = V2*255*65536;
  763.       } // End for
  764.   } // End of MapTexture for G3DPOLYHEDRON 
  765.  
  766. VOID G3DPOLYHEDRON::Init ()
  767.   {
  768.     ComputeCenter ();
  769.     
  770.     LISTOBJECT<G3DOBJECT*> *ObjectNode;
  771.     ObjectNode = SubObjectList->GetHead ();
  772.  
  773.     while (ObjectNode!=NULL)
  774.       {
  775.         ObjectNode->Data->Init ();
  776.         ObjectNode = ObjectNode->NextObject;  
  777.       } // End while
  778.       
  779.     CountPointShare ();
  780.     ComputePolyLocalNormals ();
  781.     ComputePointLocalNormals ();
  782.   } // End of Init for G3DPOLYHEDRON
  783.  
  784. VOID G3DPOLYHEDRON::CountShapes ( LONG *Count )
  785.   {
  786.     *Count += GeometryData.NumPolys;  
  787.   } // End of CountShapes for G3DPOLYHEDRON
  788.  
  789. VOID G3DPOLYHEDRON::ComputeCenter ()
  790.   {
  791.     LONG i;
  792.     float MinX,MaxX;
  793.     float MinY,MaxY;
  794.     float MinZ,MaxZ;
  795.  
  796.     if (GeometryData.FLPLocalPoints==NULL)
  797.       {
  798.         return;
  799.       } // End if
  800.  
  801.     MinX = MaxX = GeometryData.FLPLocalPoints[0].x;
  802.     MinY = MaxY = GeometryData.FLPLocalPoints[0].y;
  803.     MinZ = MaxZ = GeometryData.FLPLocalPoints[0].z;
  804.  
  805.     for (i=1;i<GeometryData.NumPoints;i++)
  806.       {
  807.         if (GeometryData.FLPLocalPoints[i].x<MinX)
  808.           MinX = GeometryData.FLPLocalPoints[i].x;
  809.         else if (GeometryData.FLPLocalPoints[i].x>MaxX)  
  810.           MaxX = GeometryData.FLPLocalPoints[i].x;
  811.           
  812.         if (GeometryData.FLPLocalPoints[i].y<MinY)
  813.           MinY = GeometryData.FLPLocalPoints[i].y;  
  814.         else if (GeometryData.FLPLocalPoints[i].y>MaxY)  
  815.           MaxY = GeometryData.FLPLocalPoints[i].y;
  816.           
  817.         if (GeometryData.FLPLocalPoints[i].y<MinZ)
  818.           MinZ = GeometryData.FLPLocalPoints[i].z;  
  819.         else if (GeometryData.FLPLocalPoints[i].z>MaxZ)  
  820.           MaxZ = GeometryData.FLPLocalPoints[i].z;
  821.       } // End for
  822.  
  823.     FLPLocalCenter.x = ( MaxX + MinX ) / 2; 
  824.     FLPLocalCenter.y = ( MaxY + MinY ) / 2; 
  825.     FLPLocalCenter.z = ( MaxZ + MinZ ) / 2; 
  826.   } // End of ComputeCenter for G3DPOLYHEDRON
  827.  
  828. float G3DPOLYHEDRON::ComputeRadius ()
  829.   {
  830.     float Distance;
  831.     float MaxDist;
  832.  
  833.     LONG i;
  834.  
  835.     MaxDist = (float)0;
  836.     FLPVECTOR3D Center;
  837.     FLPVECTOR3D Point;
  838.  
  839.     Center = FLPLocalCenter;
  840.         
  841.     for (i=0;i<GeometryData.NumPoints;i++)
  842.       {
  843.         Point = GeometryData.FLPLocalPoints[i];
  844.         Distance = FLPVectorDistance ( &Center,
  845.                                        &Point );
  846.         if (MaxDist<Distance)
  847.           MaxDist = Distance;          
  848.       } // End for
  849.     
  850.     LISTOBJECT<G3DOBJECT*> *ObjectNode;
  851.     FLPVECTOR3D SubCenter;
  852.     G3DOBJECT *Object;
  853.     ObjectNode = SubObjectList->GetHead ();
  854.  
  855.     while (ObjectNode!=NULL)
  856.       {
  857.         Object = ObjectNode->Data;
  858.         SubCenter = Object->GetLocalCenter ();
  859.         Distance = Object->ComputeRadius ();
  860.         Distance += FLPVectorDistance ( &FLPLocalCenter, &SubCenter );
  861.         if (MaxDist<Distance)
  862.           MaxDist = Distance;
  863.         ObjectNode = ObjectNode->NextObject;  
  864.       } // End while
  865.  
  866.     Radius = MaxDist;  
  867.     return MaxDist;  
  868.   } // End of ComputeRadius for G3DPOLYHEDRON
  869.   
  870. float G3DPOLYHEDRON::ComputeTforPoly ( FLPVECTOR3D Normal, FLPVECTOR3D Base, FLPVECTOR3D Dir )
  871.   {
  872.     float T;
  873.     float Denom,Value;
  874.       
  875.     Denom = Normal.x*Dir.x+Normal.y*Dir.y+Normal.z*Dir.z;
  876.     Value = Normal.x*Base.x+Normal.y*Base.y+Normal.z*Base.z+Normal.w;
  877.     if (Denom==0)
  878.       return (float)(-1);
  879.  
  880.     T = (-Value)/Denom;  
  881.     
  882.     return T;       
  883.   } // End of ComputeTforPoly for G3DPOLYHEDRON
  884.  
  885. VOID G3DPOLYHEDRON::CheckCollision ( FLPVECTOR3D StartPt, FLPVECTOR3D EndPt,
  886.                                      COLLIDEDATA* CollideList, LONG *CurNum, LONG MaxNum,
  887.                                      float CollideDist, float Gap )
  888.   {
  889.     if (*CurNum>=MaxNum)
  890.       return;
  891.         
  892.     float MinX,MinY,MinZ;      
  893.     float MaxX,MaxY,MaxZ;
  894.  
  895.     MinX = FLPWorldCenter.x - Radius;
  896.     MaxX = FLPWorldCenter.x + Radius;
  897.     MinY = FLPWorldCenter.y - Radius;
  898.     MaxY = FLPWorldCenter.y + Radius;    
  899.     MinZ = FLPWorldCenter.z - Radius;
  900.     MaxZ = FLPWorldCenter.z + Radius;
  901.  
  902.     if (((StartPt.x>MinX)&&(StartPt.x<MaxX)&&
  903.           (StartPt.y>MinY)&&(StartPt.y<MaxY)&&
  904.            (StartPt.z>MinZ)&&(StartPt.z<MaxZ)) ||
  905.         ((EndPt.x>MinX)&&(EndPt.x<MaxX)&&
  906.           (EndPt.y>MinY)&&(EndPt.y<MaxY)&&
  907.            (EndPt.z>MinZ)&&(EndPt.z<MaxZ)))
  908.       {
  909.         FLPVECTOR3D Dir,Normal;
  910.         G3DPOLY *Polys;
  911.         FLPVECTOR3D *NormalPtr;
  912.         FLPVECTOR3D **PolyPointPtr;
  913.         float wx,wy,wz;
  914.  
  915.         FLPVectorSub ( &StartPt, &EndPt, &Dir );
  916.         Polys = GeometryData.Polys;
  917.         PolyPointPtr = GeometryData.FLPPolyWorldPoints;
  918.         NormalPtr = GeometryData.FLPPolyWorldNormals;
  919.         LONG i;
  920.         for (i=0;i<GeometryData.NumPolys;i++)
  921.           {
  922.             wx = (*PolyPointPtr)->x;  
  923.             wy = (*PolyPointPtr)->y;  
  924.             wz = (*PolyPointPtr)->z;
  925.             Normal.x = NormalPtr->x;
  926.             Normal.y = NormalPtr->y;
  927.             Normal.z = NormalPtr->z;
  928.             Normal.w = -(Normal.x*wx+Normal.y*wy+Normal.z*wz);
  929.             float T;
  930.             FLPVECTOR3D I; // Intersection Point
  931.             
  932.             T = ComputeTforPoly ( Normal, StartPt, Dir );
  933.             if ((T>0)&&(T<CollideDist))
  934.               {
  935.                 I.x = StartPt.x + T*Dir.x;  
  936.                 I.y = StartPt.y + T*Dir.y;  
  937.                 I.z = StartPt.z + T*Dir.z;
  938.                 if ((I.x>Polys->WorldMinX-Gap)&&(I.x<Polys->WorldMaxX+Gap)&&
  939.                       (I.y>Polys->WorldMinY-Gap)&&(I.y<Polys->WorldMaxY+Gap)&&
  940.                        (I.z>Polys->WorldMinZ-Gap)&&(I.z<Polys->WorldMaxZ+Gap))
  941.                   {
  942.                     CollideList[*CurNum].Shape = Polys;
  943.                     CollideList[*CurNum].CollideT = T;
  944.                     (*CurNum)++;
  945.                     if (*CurNum>=MaxNum)
  946.                       return;                    
  947.                   } // End if     
  948.               } // End if
  949.             Polys++;
  950.             PolyPointPtr++;
  951.             NormalPtr++;
  952.           } // End for  
  953.         LISTOBJECT<G3DOBJECT*> *ObjectNode;
  954.         G3DOBJECT *Object;
  955.         ObjectNode = SubObjectList->GetHead ();
  956.  
  957.         while (ObjectNode!=NULL)
  958.           {
  959.             Object = ObjectNode->Data;
  960.             Object->CheckCollision ( StartPt, EndPt, CollideList, CurNum, MaxNum,
  961.                                      CollideDist, Gap );
  962.             ObjectNode = ObjectNode->NextObject;  
  963.           } // End while
  964.       } // End if                 
  965.   } // End of CheckCollision for G3DPOLYHEDRON  
  966.  
  967. BOOLEAN G3DPOLYHEDRON::CreateMorphData ( GEOMETRYDATA *TargetGeometry, LONG NumFrames )
  968.   {
  969.     if (NumFrames<=0)
  970.       return FAILURE;
  971.         
  972.     FLPVECTOR3D *NewPoints;
  973.     FLPVECTOR3D *OldPoints;
  974.  
  975.     NewPoints = TargetGeometry->FLPLocalPoints;
  976.     OldPoints = GeometryData.FLPLocalPoints;
  977.  
  978.     DestroyMorphData ();
  979.     MorphData = new MORPHDATA;
  980.     if (MorphData==NULL)
  981.       return FAILURE;
  982.     MorphData->FLPLocalPointsDelta = new FLPVECTOR3D [TargetGeometry->NumPoints];
  983.     if (MorphData->FLPLocalPointsDelta==NULL)
  984.       DestroyMorphData ();
  985.     MorphData->NumFrames = NumFrames;
  986.  
  987.     LONG i;
  988.     float Ratio;
  989.     Ratio = (float)1/NumFrames;
  990.     FLPVECTOR3D *Deltas;
  991.  
  992.     Deltas = MorphData->FLPLocalPointsDelta;
  993.     for (i=0;i<TargetGeometry->NumPoints;i++)
  994.       {
  995.         Deltas->x = (NewPoints->x-OldPoints->x)*Ratio;
  996.         Deltas->y = (NewPoints->x-OldPoints->y)*Ratio;
  997.         Deltas->z = (NewPoints->x-OldPoints->z)*Ratio;
  998.         Deltas++;
  999.         NewPoints++;
  1000.         OldPoints++;
  1001.       } // End for
  1002.     MorphData->CurFrame = 0;
  1003.     return 0;
  1004.   } // End of CreateMorhData for G3DPOLYHEDRON
  1005.   
  1006. VOID G3DPOLYHEDRON::DestroyMorphData ()
  1007.   {
  1008.     if (MorphData!=NULL)
  1009.       {
  1010.         if (MorphData->FLPLocalPointsDelta!=NULL)
  1011.           delete MorphData->FLPLocalPointsDelta;  
  1012.         delete MorphData;
  1013.       } // End if  
  1014.     MorphData = NULL;
  1015.   } // End of DestroyMorhData for G3DPOLYHEDRON
  1016.  
  1017. VOID G3DPOLYHEDRON::Warp ( LONG NumSteps )
  1018.   {
  1019.     if (MorphData==NULL)
  1020.       return;
  1021.     if (MorphData->FLPLocalPointsDelta==NULL)
  1022.       return;
  1023.  
  1024.     FLPVECTOR3D *Deltas;
  1025.     FLPVECTOR3D *Points;
  1026.     LONG i;
  1027.     
  1028.     Deltas = MorphData->FLPLocalPointsDelta;
  1029.     Points = GeometryData.FLPLocalPoints;
  1030.  
  1031.     if (NumSteps+MorphData->CurFrame>=MorphData->NumFrames)
  1032.       NumSteps = MorphData->NumFrames-MorphData->CurFrame-1;
  1033.       
  1034.     if (NumSteps<=0)
  1035.       return;
  1036.  
  1037.     if (NumSteps==1)
  1038.       {
  1039.         for (i=0;i<GeometryData.NumPoints;i++)
  1040.           {
  1041.             Points->x += Deltas->x;  
  1042.             Points->y += Deltas->y;  
  1043.             Points->z += Deltas->z;
  1044.             Points++;
  1045.             Deltas++;
  1046.           } // End for  
  1047.       } // End if
  1048.     else
  1049.       {
  1050.         for (i=0;i<GeometryData.NumPoints;i++)
  1051.           {
  1052.             Points->x += Deltas->x*NumSteps;  
  1053.             Points->y += Deltas->y*NumSteps;  
  1054.             Points->z += Deltas->z*NumSteps;
  1055.             Points++;
  1056.             Deltas++;
  1057.           } // End for  
  1058.       } // End else
  1059.       
  1060.     MorphData->CurFrame++;
  1061.     if (MorphData->CurFrame>=MorphData->NumFrames-1)
  1062.       DestroyMorphData ();
  1063.   } // End of Warp for G3DPOLYHEDRON
  1064.  
  1065.  
  1066.